import Decimal from '@/libs/decimal.min.js'
import LocalStorage from '@/utils/LocalStorage.js'
import _ from '@/libs/lodash.min.js'

let Utils = {
  makePromise () {
    let resolveHandle
    let rejectHandle
    let promise = new Promise((resolve, reject) => {
      resolveHandle = (response) => {
        resolve(response)
      }
      rejectHandle = (response) => {
        reject(response)
      }
    })
    promise.resolveHandle = resolveHandle
    promise.rejectHandle = rejectHandle
    return promise
  },
  // 实例：formatDate(new Date('2017-10-10 10:10:10'), 'hh:MM:ss')可得到10:10:10
  formatDate: function (dateObj, format) { // dateObj必须为Date对象
    var o = {
      'M+': dateObj.getMonth() + 1, // month
      'd+': dateObj.getDate(), // day
      'h+': dateObj.getHours(), // hour
      'm+': dateObj.getMinutes(), // minute
      's+': dateObj.getSeconds(), // second
      'q+': Math.floor((dateObj.getMonth() + 3) / 3), // quarter
      'S': dateObj.getMilliseconds() // millisecond
    }
    var week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
    if (/(y+)/.test(format)) {
      format = format.replace(RegExp.$1, (dateObj.getFullYear() + '').substr(4 - RegExp.$1.length))
    }
    if (/(w+)/.test(format)) {
      format = format.replace(RegExp.$1, week[dateObj.getDay()])
    }
    for (var k in o) {
      if (new RegExp('(' + k + ')').test(format)) {
        format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
      }
    }
    return format
  },
  getDateValues (dateObj) {
    return {
      year: dateObj.getFullYear(),
      'month': dateObj.getMonth() + 1, // month
      'day': dateObj.getDate(), // day
      'hours': dateObj.getHours(), // hour
      'minutes': dateObj.getMinutes(), // minute
      'seconds': dateObj.getSeconds(), // second
      'milliseconds': dateObj.getMilliseconds() // millisecond
    }
  },
  isFunction (fn) {
    return typeof Function === 'function'
  },
  copyObject (obj) {
    return JSON.parse(JSON.stringify(obj))
  },
  // 根据该时间偏移和该时间戳得出各地本地时间
  getLocalTimestamp: (thisOffset, thisTimestamp) => { // 这里的时间戳是以秒为单位
    // 计算该时的世界时
    var thisUTCTimestamp = 0
    if (thisOffset < 0) {
      // thisOffset-8表示领先世界时间8小时，即世界时间是在8小时后，要得到世界时间需要+8
      thisOffset = Math.abs(thisOffset)
      thisUTCTimestamp = thisTimestamp + thisOffset * 60 * 60 // 得到该时间世界时的时间戳
    } else {
      thisUTCTimestamp = thisTimestamp - thisOffset * 60 * 60
    }

    // 根据上面的世界时时间戳得到本地时区的时间戳
    let date = new Date()
    let localOffset = date.getTimezoneOffset() // 当地时区对世界时的偏移，单位是分钟
    let localTimestamp = 0
    if (localOffset < 0) {
      localOffset = Math.abs(localOffset)
      // localOffset为-8为领先世界时8小时，则当地时是在世界时的前面，用世界时减去当地时偏移得出当地时
      localTimestamp = thisUTCTimestamp - localOffset * 60
    } else {
      // 如果为8，则当地时间在世界时间后面，则世界时间+8等于当地时间
      localTimestamp = thisUTCTimestamp + localOffset * 60
    }
    return localTimestamp
  },
  // IE11不认xxxx-xx-xx这种格式，故把-换成/
  fixNewDateForIE: (dateStr) => {
    var date = new Date(dateStr)
    if (!date.getTime() || date === 'Invalid Date') {
      date = new Date(dateStr.replace(/-/g, '/'))
    }
    return date
  },
  fixNewDateStringForIE (dateString) {
    return dateString.replace(/-/g, '/')
  },
  fixNewDateStringWithArrayForIE (list = [], dateKey) {
    for (let i = 0; i < list.length; i++) {
      list[i][dateKey] = Utils.fixNewDateStringForIE(list[i][dateKey])
    }
  },
  // 时间本地化
  localTime: function (list, timeName) {
    if (!Array.isArray(list) || !list.length) return list
    let date
    let thisTimestamp
    let localTimestamp
    for (var i = 0; i < list.length; i++) {
      date = Utils.fixNewDateForIE(list[i][timeName]) // ie下不认以“-”作格式的时间
      thisTimestamp = date.getTime()
      localTimestamp = this.getLocalTimestamp(-8, thisTimestamp / 1000)
      date.setTime(localTimestamp * 1000)
      list[i][timeName] = date.format('yyyy/MM/dd hh:mm:ss')
    }
    return list
  },
  // 根据该时间偏移和该时间戳得出UTC时间
  setUTCWithArray: function (array, dateKey) {
    let thisUTCTimestamp = 0
    let date
    for (var i = 0; i < array.length; i++) {
      // 计算该时的世界时
      date = Utils.fixNewDateForIE(array[i][dateKey])
      thisUTCTimestamp = Date.UTC(
        date.getFullYear(),
        date.getMonth(),
        date.getDate(),
        date.getHours(),
        date.getMinutes(),
        date.getSeconds()
      )
      date.setTime(thisUTCTimestamp)
      array[i][dateKey] = Utils.formatDate(date, 'yyyy/MM/dd hh:mm:ss')
    }
  },
  // 代替原生的toFxied，因为原生的必须要求是浮点类型，如果用其它数据类型会报错
  toFixed: (n, l) => {
    if (!/^-?\d*\.*\d+$/.test(n)) return n
    return n.toFixed(l)
  },
  // 修复1e-8精度问题，按照原来的位数格式化
  fixOriginalPrecisionWithArray (list = [], key) {
    for (let i = 0; i < list.length; i++) {
      if (parseFloat(list[i][key])) {
        list[i][key] = (new Decimal(list[i][key])).toFixed()
      }
    }
  },
  // 按照指定的位数格式化
  toFixedWithArray: (arr, key, len) => {
    for (let i = 0; i < arr.length; i++) {
      arr[i][key] = Utils.toFixed(arr[i][key], len)
    }
  },
  // 给数组添加key访问
  definePropertyForArray (arr, key) {
    arr.forEach((item, index) => {
      // 不存在相同的key
      !arr[item[key]] && Object.defineProperty(arr, item[key], {
        Enumerable: false,
        value: item
      })
    })
  },
  // 返回小数点
  getDecimals (val = '') {
    return val.split('.')[1] || ''
  },
  // localStorage
  LS: LocalStorage,
  onlyNumber (input, cb) {
    let val = input.value
    val = val.replace(/\D/g, '')
    input.value = val

    _.isFunction(cb) && cb(val)
  },
  toQueryString: (json = {}) => {
    var arr = []
    for (let key in json) {
      arr.push(key + '=' + json[key])
    }
    return arr.join('&')
  },
  // 例：siteName，替换lang里的{siteName}为conifg的siteName
  replaceText (text, configKey, configKeyValue) {
    if (typeof text !== 'string') return text

    return text.replace(new RegExp('\\{' + configKey + '\\}', 'g'), configKeyValue)
  },
}

export default Utils
